package com.sdwz.borrow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sdwz.borrow.client.LibraryClient;
import com.sdwz.borrow.client.UserClient;
import com.sdwz.borrow.entity.*;
import com.sdwz.borrow.entity.vo.BorrowInfoVo;
import com.sdwz.borrow.mapper.BorrowInfoMapper;
import com.sdwz.borrow.service.AppointmentInfoService;
import com.sdwz.borrow.service.BorrowInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sdwz.borrow.service.PenaltyInfoService;
import com.sdwz.commonutil.exception.LibraryException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;

/**
 * <p>
 * 借阅信息表 服务实现类
 * </p>
 *
 * @author testjava
 * @since 2021-03-30
 */
@Service
public class BorrowInfoServiceImpl extends ServiceImpl<BorrowInfoMapper, BorrowInfo> implements BorrowInfoService {

    @Autowired
    AppointmentInfoService appointmentInfoService;

    @Autowired
    LibraryClient libraryClient;

    @Autowired
    UserClient userClient;

    @Autowired
    PenaltyInfoService penaltyInfoService;
    /**
     * 取书（预约表状态改为完成借阅，借阅表中添加借阅信息）
     * @param appoId
     */
    @Override
    public void getBook(String appoId) {
        AppointmentInfo appointmentInfo = appointmentInfoService.getById(appoId);
        if (appointmentInfo==null){
            throw new LibraryException(201,"当前预约信息不存在");
        }

        if (appointmentInfo.getEndTime().before(new Date())){
            throw new LibraryException(201,"超期未取书");
        }
        appointmentInfo.setStatus(1);
        appointmentInfoService.updateById(appointmentInfo);

        BorrowInfo borrowInfo = new BorrowInfo();
        borrowInfo.setUserId(appointmentInfo.getUserId());
        borrowInfo.setBookId(appointmentInfo.getBookId());
        borrowInfo.setAppoId(appoId);
        borrowInfo.setStartTime(new Date());
        LocalDateTime localDateTime = LocalDateTime.now().plusDays(3);
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);//Combines this date-time with a time-zone to create a  ZonedDateTime.
        Date date = Date.from(zdt.toInstant());
        borrowInfo.setEndTime(date);
        borrowInfo.setStatus(1);

        baseMapper.insert(borrowInfo);
    }

    /**
     * 查询借阅记录列表
     * @param current
     * @param limit
     * @param borrowInfoVo
     * @return
     */
    @Override
    public Map<String,Object>getBorrowInfoList(Long current, Long limit, BorrowInfoVo borrowInfoVo) {
        Map<String,Object> result = new HashMap<>();
        Page<BorrowInfo> page = new Page<>(current,limit);

        QueryWrapper<BorrowInfo> wrapper = new QueryWrapper<>();
        String userId = borrowInfoVo.getUserId();
        String bookId = borrowInfoVo.getBookId();
        Integer status = borrowInfoVo.getStatus();

        if (userId != null){
            wrapper.eq("user_id",userId);
        }
        if (bookId != null){
            wrapper.eq("book_id",bookId);
        }
        if (status != null && status != -1){
            wrapper.eq("status",status);
        }else if (status != null && status == -1){
            wrapper.eq("status",1);
            wrapper.lt("end_time",new Date());
        }
        Page<BorrowInfo> page1 = baseMapper.selectPage(page, wrapper);
        List<BorrowInfo> records = page1.getRecords();
        long current1 = page1.getCurrent();
        long size = page1.getSize();
        long total = page1.getTotal();

        List<BorrowInfoVo> borrowInfoVos = new ArrayList<>();
        for (BorrowInfo borrowInfo:records){
            BorrowInfoVo borrowInfoVo1 = new BorrowInfoVo();
            BeanUtils.copyProperties(borrowInfo,borrowInfoVo1);


            String userId1 = borrowInfo.getUserId();
            String bookId1 = borrowInfo.getBookId();

            BookInfo book = libraryClient.getBook(bookId1);
            borrowInfoVo1.setBookName(book.getBookName());
            borrowInfoVo1.setAuthor(book.getAuthor());
            borrowInfoVo1.setISBN(book.getISBN());

            UserInfo userInfo = userClient.getUser(userId1);
            borrowInfoVo1.setName(userInfo.getName());
            borrowInfoVo1.setNickName(userInfo.getNickName());

            if (borrowInfoVo1.getStatus() ==1 &&borrowInfoVo1.getEndTime().before(new Date())){
                borrowInfoVo1.setStatus(-1);
            }


            borrowInfoVos.add(borrowInfoVo1);

        }

        result.put("total",total);
        result.put("size",size);
        result.put("current",current1);
        result.put("records",borrowInfoVos);
        return result;
    }


    @Override
    public Map<String,Object> getInList(Long current, Long limit, BorrowInfoVo borrowInfoVo) {
        Map<String,Object> result = new HashMap<>();
        Page<BorrowInfo> page = new Page<>(current,limit);

        QueryWrapper<BorrowInfo> wrapper = new QueryWrapper<>();
        String userId = borrowInfoVo.getUserId();
        String bookId = borrowInfoVo.getBookId();
        Integer status = borrowInfoVo.getStatus();

        wrapper.ne("status",0).ne("status",1).ne("status",-3);

        if (userId != null){
            wrapper.eq("user_id",userId);
        }
        if (bookId != null){
            wrapper.eq("book_id",bookId);
        }
        if (status != null){
            wrapper.eq("status",status);
        }
        Page<BorrowInfo> page1 = baseMapper.selectPage(page, wrapper);
        List<BorrowInfo> records = page1.getRecords();
        long current1 = page1.getCurrent();
        long size = page1.getSize();
        long total = page1.getTotal();

        List<BorrowInfoVo> borrowInfoVos = new ArrayList<>();
        for (BorrowInfo borrowInfo:records){
            BorrowInfoVo borrowInfoVo1 = new BorrowInfoVo();
            BeanUtils.copyProperties(borrowInfo,borrowInfoVo1);


            String userId1 = borrowInfo.getUserId();
            String bookId1 = borrowInfo.getBookId();

            BookInfo book = libraryClient.getBook(bookId1);
            borrowInfoVo1.setBookName(book.getBookName());
            borrowInfoVo1.setAuthor(book.getAuthor());
            borrowInfoVo1.setISBN(book.getISBN());

            UserInfo userInfo = userClient.getUser(userId1);
            borrowInfoVo1.setName(userInfo.getName());
            borrowInfoVo1.setNickName(userInfo.getNickName());


            borrowInfoVos.add(borrowInfoVo1);

        }

        result.put("total",total);
        result.put("size",size);
        result.put("current",current1);
        result.put("records",borrowInfoVos);
        return result;
    }

    /**
     * 获取当前用户借阅中的借阅记录
     * @param userId
     * @return
     */
    @Override
    public List<BorrowInfoVo> getBorrowingInfo(Long userId) {
        List<BorrowInfoVo> borrowInfoVos = new ArrayList<>();

        QueryWrapper<BorrowInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",String.valueOf(userId));
        wrapper.ne("status",0).ne("status",-3);

        List<BorrowInfo> borrowInfos = baseMapper.selectList(wrapper);

        for (BorrowInfo borrowInfo:borrowInfos){
            BorrowInfoVo borrowInfoVo = new BorrowInfoVo();
            BeanUtils.copyProperties(borrowInfo,borrowInfoVo);


            String userId1 = borrowInfo.getUserId();
            String bookId1 = borrowInfo.getBookId();

            BookInfo book = libraryClient.getBook(bookId1);
            borrowInfoVo.setBookName(book.getBookName());
            borrowInfoVo.setAuthor(book.getAuthor());
            borrowInfoVo.setISBN(book.getISBN());

            UserInfo userInfo = userClient.getUser(userId1);
            borrowInfoVo.setName(userInfo.getName());
            borrowInfoVo.setNickName(userInfo.getNickName());

            if (borrowInfoVo.getStatus() ==1 && borrowInfoVo.getEndTime().before(new Date())){
                borrowInfoVo.setStatus(-1);
            }
            borrowInfoVos.add(borrowInfoVo);
        }
        return borrowInfoVos;
    }

    /**
     * 获取当前用户的借阅历史
     * @param userId
     * @param current
     * @param limit
     * @return
     */
    @Override
    public Map<String, Object> getBorrowHistoryInfo(String userId, Long current, Long limit) {
        Map<String,Object> result = new HashMap<>();
        Page<BorrowInfo> page = new Page<>(current,limit);

        QueryWrapper<BorrowInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        wrapper.eq("status",0);

        Page<BorrowInfo> page1 = baseMapper.selectPage(page, wrapper);
        List<BorrowInfo> records = page1.getRecords();
        long current1 = page1.getCurrent();
        long size = page1.getSize();
        long total = page1.getTotal();

        List<BorrowInfoVo> borrowInfoVos = new ArrayList<>();
        for (BorrowInfo borrowInfo:records){
            BorrowInfoVo borrowInfoVo1 = new BorrowInfoVo();
            BeanUtils.copyProperties(borrowInfo,borrowInfoVo1);


            String userId1 = borrowInfo.getUserId();
            String bookId1 = borrowInfo.getBookId();

            BookInfo book = libraryClient.getBook(bookId1);
            borrowInfoVo1.setBookName(book.getBookName());
            borrowInfoVo1.setAuthor(book.getAuthor());
            borrowInfoVo1.setISBN(book.getISBN());

            UserInfo userInfo = userClient.getUser(userId1);
            borrowInfoVo1.setName(userInfo.getName());
            borrowInfoVo1.setNickName(userInfo.getNickName());

            borrowInfoVos.add(borrowInfoVo1);

        }

        result.put("total",total);
        result.put("size",size);
        result.put("current",current1);
        result.put("records",borrowInfoVos);
        return result;
    }

    @Override
    public void toReturnBook(String userId, String bookId) {
        //考虑借了同一本书
        QueryWrapper<BorrowInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId).eq("book_id",bookId).ge("end_time",new Date());

        List<BorrowInfo> borrowInfos = baseMapper.selectList(wrapper);
        if (borrowInfos==null){
            throw new LibraryException(201,"还书失败");
        }
        BorrowInfo borrowInfo =borrowInfos.get(0);
        borrowInfo.setEndTime(new Date());
        borrowInfo.setStatus(2);
        baseMapper.updateById(borrowInfo);
    }

    /**
     * 归还超时书籍
     * @param userId
     * @param bookId
     */
    @Override
    public void toReturnTimeOutBook(String userId, String bookId) {
        //考虑借了同一本书
        QueryWrapper<BorrowInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId).eq("book_id",bookId).eq("status",1).lt("end_time",new Date());

        List<BorrowInfo> borrowInfos = baseMapper.selectList(wrapper);
        if (borrowInfos==null){
            throw new LibraryException(201,"还书失败");
        }
        BorrowInfo borrowInfo =borrowInfos.get(0);
        borrowInfo.setEndTime(new Date());
        borrowInfo.setStatus(-2);
        baseMapper.updateById(borrowInfo);
    }

    /**
     * 确认还书
     * @param borrowId
     */
    @Override
    public void confirmBook(String borrowId) {
        //修改借阅表
        BorrowInfo borrowInfo = baseMapper.selectById(borrowId);
        String bookId = borrowInfo.getBookId();
        borrowInfo.setStatus(0);

        baseMapper.updateById(borrowInfo);

        //修改图书信息表可借数
        BookInfo bookInfo=new BookInfo();
        bookInfo.setId(bookId);
        bookInfo.setLoanableQuantity(libraryClient.getBook(bookId).getLoanableQuantity()+1);
        libraryClient.changeLoanableQuantity(bookInfo);

    }

    /**
     * 确认归还超时书
     * @param borrowId
     */
    @Override
    public void confirmTimeOutBook(String borrowId) {
        //修改借阅表
        BorrowInfo borrowInfo = baseMapper.selectById(borrowId);
        String bookId = borrowInfo.getBookId();
        borrowInfo.setStatus(-3);

        baseMapper.updateById(borrowInfo);



        //修改图书信息表可借数
        BookInfo bookInfo=new BookInfo();
        bookInfo.setId(bookId);
        BookInfo book =libraryClient.getBook(bookId);
        bookInfo.setLoanableQuantity(book.getLoanableQuantity()+1);
        libraryClient.changeLoanableQuantity(bookInfo);

        //添加罚款表
        PenaltyInfo penaltyInfo = new PenaltyInfo();
        penaltyInfo.setBorrowId(borrowId);
        penaltyInfo.setUserId(borrowInfo.getUserId());
        penaltyInfo.setBookId(borrowInfo.getBookId());
        int day = penaltyInfoService.calculateDay(borrowInfo.getEndTime(), new Date());
        penaltyInfo.setAmount(penaltyInfoService.calculateAmount(day,book.getPrice()));
        penaltyInfo.setSubject("逾期"+day+"天，罚款金额："+penaltyInfo.getAmount());
        penaltyInfo.setPenaltyStatus(0);

        penaltyInfoService.save(penaltyInfo);

    }
}
